﻿using JinYuan.Models.HelperAttribute;
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;



/// <summary>
/// DataTable 映射工具
/// </summary>
/// <summary>
/// DataTable 映射工具
/// </summary>
public static class DataTableMapper
{
    /// <summary>
    /// 实体类型转换为 DataTable 结构（含注解解析）
    /// </summary>
    public static DataTable ToSchema(Type type)
    {
        var dt = new DataTable(type.Name);
        var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance);

        foreach (var member in members)
        {
            var prop = member as PropertyInfo;
            var field = member as FieldInfo;
            if ((prop != null && !prop.CanRead) || (field == null && prop == null)) continue;

            var attr = member.GetCustomAttribute<DataGridColumnAttribute>();
            var colName = attr != null ? attr.ColumnName : member.Name;
            var colType = attr != null && attr.ColumnType != null ? attr.ColumnType :
                          (prop != null ? prop.PropertyType : field.FieldType);

            var column = dt.Columns.Add(colName, colType);
            column.AllowDBNull = !(colType.GetTypeInfo().IsValueType &&
                                  !colType.GetTypeInfo().IsGenericType);
        }
        return dt;
    }

    /// <summary>
    /// 实体集合转换为 DataTable（含注解映射）
    /// 使用: var dt = DataTableMapper.ToDataTable (employees, typeof (Employee));
    /// </summary>
    public static DataTable ToDataTable(this IEnumerable<object> entities, Type type)
    {
        var dt = ToSchema(type);
        if (entities == null) return dt;

        foreach (var entity in entities)
        {
            var row = dt.NewRow();
            FillDataRow(entity, row, type);
            dt.Rows.Add(row);
        }
        return dt;
    }

    private static void FillDataRow(object entity, DataRow row, Type type)
    {
        foreach (DataColumn column in row.Table.Columns)
        {
            MemberInfo member = null;
            foreach (var m in type.GetMembers(BindingFlags.Public | BindingFlags.Instance))
            {
                var attr = m.GetCustomAttribute<DataGridColumnAttribute>();
                var mName = attr != null ? attr.ColumnName : m.Name;
                if (string.Equals(mName, column.ColumnName, StringComparison.OrdinalIgnoreCase))
                {
                    member = m;
                    break;
                }
            }

            if (member == null) continue;

            object value;
            if (member is PropertyInfo prop)
            {
                value = prop.GetValue(entity);
            }
            else if (member is FieldInfo field)
            {
                value = field.GetValue(entity);
            }
            else
            {
                continue;
            }

            row[column] = value ?? DBNull.Value;
        }
    }

    /// <summary>
    /// DataTable 转换为 List<T>
    /// 使用案例： var employeeList = dt.ToList<Employee>();
    /// </summary>
    public static List<T> ToList<T>(this DataTable dt) where T : new()
    {
        var list = new List<T>();
        var type = typeof(T);
        var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance);

        foreach (DataRow row in dt.Rows)
        {
            var item = new T();
            foreach (var member in members)
            {
                var prop = member as PropertyInfo;
                var field = member as FieldInfo;
                if ((prop != null && !prop.CanWrite) || (field == null && prop == null)) continue;

                var attr = member.GetCustomAttribute<DataGridColumnAttribute>();
                var colName = attr != null ? attr.ColumnName : member.Name;
                if (dt.Columns.Contains(colName))
                {
                    var value = row[colName];
                    if (value != DBNull.Value)
                    {
                        if (prop != null)
                        {
                            prop.SetValue(item, Convert.ChangeType(value, prop.PropertyType));
                        }
                        else if (field != null)
                        {
                            field.SetValue(item, Convert.ChangeType(value, field.FieldType));
                        }
                    }
                }
            }
            list.Add(item);
        }
        return list;
    }

    /// <summary>
    /// 循环获取当前 DataTable 的列名称，通过自定义的获取名称方法获取新的列名并替换
    /// </summary>
    /// <param name="dt">要处理的 DataTable</param>
    /// <param name="getNewColumnName">自定义的获取新列名的方法</param>
    /// <returns>列名替换后的 DataTable</returns>
    public static DataTable ReplaceColumnNamesWithCustomMethod(this DataTable dt, Func<string, string> GetNewColumnName)
    {
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            string originalColumnName = dt.Columns[i].ColumnName;
            string newColumnName = GetNewColumnName(originalColumnName);
            dt.Columns[i].ColumnName = newColumnName;
        }
        return dt;
    }
}